/**
 * Licensed under the MIT License
 *
 * Copyright (c) 2010 Alexandre Croiseaux
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */
package marcel.display.gui.buttons
{
	import flash.display.DisplayObject;
	import flash.geom.ColorTransform;
	import flash.utils.Dictionary;
	import marcel.display.gui.buttons.CoreButton;
	import marcel.display.Tween;
	
	/**
	 * ColorButton Class used to create buttons with changing colors on rollOver/rollOut.
	 * @author Alexandre Croiseaux
	 */
	public class ColorButton extends CoreButton
	{
		//--------------------------------------------------------------------------
		//
		//  Private vars
		//
		//--------------------------------------------------------------------------
		private var _colorClips:Dictionary;
		
		//--------------------------------------------------------------------------
		//
		//  Public methods
		//
		//--------------------------------------------------------------------------
		/**
		 * Public untyped property to store arbitrary data
		 */
		public var data:*;
		
		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------
		/**
		 * Constructs a new ColorButton instance.
		 */
		public function ColorButton()
		{
			_colorClips = new Dictionary(true);
		}
		
		
		//--------------------------------------------------------------------------
		//
		//  Public methods
		//
		//--------------------------------------------------------------------------
		/**
		 * Registers a DisplayObject instance that should change its color on over/out mouse events.
		 * @param	target		a DisplayObject instance that should change its color
		 * @param	colorOver	the color value when the mouse is over the button
		 * @param	colorOut	the color value when the mouse is out the button
		 * @param	duration	the duration of the color transition, in seconds
		 * @param	easing		the easing function used for the color transition
		 */
		public function registerColor(target:DisplayObject, colorOver:uint, colorOut:uint, duration:Number = .5, easing:Function = null):void
		{
			_colorClips[target] = {over:colorOver, out:colorOut, duration:duration, useColorTransform:false, easing:easing};
		}
		
		/**
		 * Registers a DisplayObject instance that should change its colorTransform property on over/out mouse events.
		 * @param	target		a DisplayObject instance that should change its colorTransform property
		 * @param	colorOver	the color value when the mouse is over the button, use null to reset the colorTransform
		 * @param	colorOut	the color value when the mouse is out the button, use null to reset the colorTransform
		 * @param	duration	the duration of the color transition, in seconds
		 * @param	easing		the easing function used for the color transition
		 */
		public function registerColorTransform(target:DisplayObject, colorOver:ColorTransform, colorOut:ColorTransform = null, duration:Number = .5, easing:Function = null):void
		{
			_colorClips[target] = {over:colorOver, out:colorOut, duration:duration, useColorTransform:true, easing:easing};
		}
		
		/**
		 * Applies the colorOver to all registered clips immediately, with no fade effect (duration = 0)
		 */
		public function setOver():void
		{
			updateColor(true, false);
		}
		
		/**
		 * Applies the colorOut to all registered clips immediately, with no fade effect (duration = 0)
		 */
		public function setOut():void
		{
			updateColor(false, false);
		}
		
		
		//--------------------------------------------------------------------------
		//
		//  Private methods
		//
		//--------------------------------------------------------------------------
		private function updateColor(over:Boolean, respectFade:Boolean = true):void
		{
			for (var key:Object in _colorClips)
			{
				var o:Object = _colorClips[key];
				var clip:DisplayObject = key as DisplayObject;
				
				if (o.useColorTransform)
				{
					var colt:ColorTransform = over ? o.over : o.out;
					if (o.duration == 0 || !respectFade) clip.transform.colorTransform = colt == null ? new ColorTransform() : colt;
					else Tween.colorTo(clip, colt.color, o.duration, o.easing);
				}
				else
				{
					var col:uint = over ? o.over : o.out;
					if (o.duration == 0 || !respectFade)
					{
						var newColorTransform:ColorTransform = clip.transform.colorTransform;
						newColorTransform.color = col;
						clip.transform.colorTransform = newColorTransform;
					}
					else Tween.colorTo(clip, col, o.duration, o.easing);
				}
			}
		}
		
		
		
		//--------------------------------------------------------------------------
		//
		//  Events
		//
		//--------------------------------------------------------------------------
		/**
		 * Changes automatically all registered clip colors when the mouse rolls over the sensor.
		 */
		public override function onOver():void
		{
			updateColor(true, true);
		}
		
		/**
		 * Changes automatically all registered clip colors when the mouse rolls out the sensor.
		 */
		public override function onOut():void
		{
			updateColor(false, true);
		}
	}
}